package com.dd.cloud.user.service.consule.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.admin.AdminUser;
import com.dd.cloud.user.entity.consult.WebSocketImMsg;
import com.dd.cloud.user.entity.consult.WebSocketPrivateGroup;
import com.dd.cloud.user.mapper.consult.WebSocketImMsgMapper;
import com.dd.cloud.user.req.consult.WebSocketReq;
import com.dd.cloud.user.res.doctor.DoctorDetailRes;
import com.dd.cloud.user.service.admin.IAdminUserService;
import com.dd.cloud.user.service.consule.IWebSocketImMsgService;
import com.dd.cloud.user.service.consule.IWebSocketPrivateGroupService;
import com.dd.cloud.user.service.doctor.IDoctorDetailService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * webSocketIm聊天消息表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2024-02-20
 */
@Service
public class WebSocketImMsgServiceImpl extends ServiceImpl<WebSocketImMsgMapper, WebSocketImMsg> implements IWebSocketImMsgService {
    @Autowired
    private IWebSocketPrivateGroupService webSocketPrivateGroupService;
    @Autowired
    private IAdminUserService adminUserService;
    @Autowired
    private IDoctorDetailService doctorDetailService;

    @Override
    public List<WebSocketImMsg> queryWebSocketImMsg(Integer privateGroupId) {
        LambdaQueryWrapper<WebSocketImMsg> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WebSocketImMsg::getPrivateGroupId, privateGroupId).orderByAsc(WebSocketImMsg::getCreateDate);
        List<WebSocketImMsg> list = this.list(queryWrapper);
        return list;
    }

    /**
     * 运营后台查询聊天记录
     *
     * @param privateGroupId 私聊id
     * @param type           消息类型 1文字 2图片
     * @param keyword        关键字
     * @return
     */
    @Override
    public Object queryWebSocketImMsgSystem(Integer privateGroupId, Integer type, String keyword) {
        WebSocketPrivateGroup webSocketPrivateGroup = webSocketPrivateGroupService.getById(privateGroupId);
        if (webSocketPrivateGroup == null) {
            throw new ZekeException("私聊记录不存在");
        }
        AdminUser adminUser = adminUserService.getById(webSocketPrivateGroup.getAdminUserId());
        DoctorDetailRes dd = doctorDetailService.queryDoctorDetail(webSocketPrivateGroup.getDoctorId());
        LambdaQueryWrapper<WebSocketImMsg> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WebSocketImMsg::getPrivateGroupId, privateGroupId).eq(WebSocketImMsg::getType, type).orderByAsc(WebSocketImMsg::getCreateDate);
        if (StringUtils.isNotBlank(keyword)) {
            queryWrapper.like(WebSocketImMsg::getContent, keyword);
        }
        List<WebSocketImMsg> list = this.list(queryWrapper);
        for (WebSocketImMsg item : list) {
            if (item.getFromUserType() == LoginInfo.UserType.DOCTOR) {
                item.setFromUserName(dd.getName());
                item.setFromUserImg(dd.getAvatar());
                item.setToUserName(adminUser.getNickName());
                item.setToUserImg("无");
            } else {
                item.setToUserName(dd.getName());
                item.setToUserImg(dd.getAvatar());
                item.setFromUserName(adminUser.getNickName());
                item.setFromUserImg("无");
            }
        }
        Object res;
        if (type == null || type == 1) {
            res = list;
        } else {
            Map<String, List<WebSocketImMsg>> map = new HashMap<>(list.size());
            for (WebSocketImMsg item : list) {
                String date = item.getCreateDate().toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM"));
                List<WebSocketImMsg> temp = map.computeIfAbsent(date, k -> new ArrayList<>());
                temp.add(item);
            }
            res = map;
        }
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWebSocketImStatus(Integer privateGroupId) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        LambdaQueryWrapper<WebSocketImMsg> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WebSocketImMsg::getStatus, 1)
                .eq(WebSocketImMsg::getPrivateGroupId, privateGroupId)
                .eq(WebSocketImMsg::getToUserType, loginInfo.getType())
                .eq(WebSocketImMsg::getToUser, loginInfo.getId());
        List<WebSocketImMsg> list = this.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            list.stream().forEach(item -> {
                item.setStatus(2);
            });
            this.updateBatchById(list);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void acceptWebSocketIm(Integer privateGroupId) {
        WebSocketPrivateGroup webSocketPrivateGroup = webSocketPrivateGroupService.getById(privateGroupId);
        if (webSocketPrivateGroup == null) {
            throw new ZekeException("记录不存在");
        }
        //更新任务列表
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        Integer adminUserId = loginInfo.getId();
        webSocketPrivateGroup.setAdminUserId(adminUserId).setStatus(2).setStartDate(LocalDateTime.now());
        webSocketPrivateGroupService.updateById(webSocketPrivateGroup);
        //更新消息记录
        LambdaQueryWrapper<WebSocketImMsg> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WebSocketImMsg::getPrivateGroupId, privateGroupId);
        List<WebSocketImMsg> list = this.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            list.stream().forEach(item -> {
                item.setToUser(loginInfo.getId());
                item.setToUserType(loginInfo.getType());
            });
            Boolean flag = this.updateBatchById(list);
            if (!flag) {
                throw new ZekeException("更新失败!");
            }
        }
    }

    /**
     * 结束更新记录
     *
     * @param privateGroupId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void endWebSocketIm(Integer privateGroupId) {
        WebSocketPrivateGroup webSocketPrivateGroup = webSocketPrivateGroupService.getById(privateGroupId);
        if (webSocketPrivateGroup == null) {
            throw new ZekeException("记录不存在");
        }
        //更新任务列表
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        Integer adminUserId = loginInfo.getId();
        webSocketPrivateGroup.setAdminUserId(adminUserId).setStatus(3).setStartDate(LocalDateTime.now());
        webSocketPrivateGroupService.updateById(webSocketPrivateGroup);
    }

    @Override
    public Integer queryNewMessage() {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer count = this.getBaseMapper().queryNewMessage(loginInfo.getId(), loginInfo.getType());
        return count;
    }

    @Override
    public WebSocketReq queryIsAcceptWebSocket(Integer privateGroupId) {
        WebSocketReq req = new WebSocketReq();
        LambdaQueryWrapper<WebSocketPrivateGroup> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WebSocketPrivateGroup::getId, privateGroupId);
        WebSocketPrivateGroup webSocketPrivateGroup = webSocketPrivateGroupService.getOne(queryWrapper);
        if (webSocketPrivateGroup == null) {
            req.setFlag(false);
            return req;
        }
        Integer status = webSocketPrivateGroup.getStatus();
        if (status == 2) {
            req.setFlag(true);
            req.setToUserId(webSocketPrivateGroup.getAdminUserId());
            return req;
        } else if (status == 1) {
            req.setFlag(false);
            return req;
        } else if (status == 3) {
            req.setFlag(false);
            req.setToUserId(webSocketPrivateGroup.getAdminUserId());
            return req;
        }
        req.setFlag(false);
        return req;
    }
}
